/*
 * Desigualdad.h
 *
 *  Created on: Jan 24, 2014
 *      Author: ik
 */

#ifndef DESIGUALDAD_H_
#define DESIGUALDAD_H_

#include <IntValueArray.h>
#include <DoubleValueArray.h>
#include <Grafo.h>
#include <Solucion.h>
#include <vector>

using namespace std;

class Desigualdad
{
	bool			_isRank;
protected:
	VertexSet*		_soporte;
	IntValueArray*	_coef;

	void resize(int nv, int nx);
public:
	Desigualdad() : _isRank(false), _soporte(NULL), _coef(NULL) {};
	Desigualdad(int nv, int nx);
	Desigualdad(const Desigualdad& otra);
	Desigualdad(const Desigualdad&& otra);
	virtual ~Desigualdad();

	Desigualdad& operator=(Desigualdad const& otra);
	Desigualdad& operator=(Desigualdad&& otra);

	virtual int getRHS() const = 0;
	virtual void setRHS(int valor) = 0;
	virtual int getCoeficiente(int i);
	const VertexSet& getSoporte() {return *_soporte;}
	virtual void setCoeficiente(int i, int coef);
	virtual const IntValueArray& getCoeficientes() { return *_coef; };
	virtual void setAsRank();
	virtual void setAsNotRank();
	virtual bool isRank();
	virtual bool estaViolada(Solucion &solucion, double violacionMinima = 0.0);
	virtual double valor(Solucion &solucion);
	virtual bool esValida(Grafo &g);
	virtual void print() = 0;
};

template <class T>
class DesigualdadArray : public vector<T>
{
protected:
	DesigualdadArray(int cap, const T& d) : vector<T>(cap, d) {};
	DesigualdadArray() : vector<T>() {};
public:
	DesigualdadArray(const DesigualdadArray<T>& otra) : vector<T>(otra) {};
	virtual ~DesigualdadArray() {};

	virtual T& operator[](int i) { return vector<T>::operator [](i); };

	virtual int getRHS() const = 0;
	virtual void setRHS(int valor) = 0;
	void setAsRank() { cout << "RepRangeDesigualdad: setAsRank not allowed." << endl; throw(-1); };
	void setAsNotRank() { cout << "RepRangeDesigualdad: setAsNotRank not allowed." << endl; throw(-1); };
	bool isRank() { return false; };
	virtual void print();
};

class FactoryDesigualdad {
public:
	FactoryDesigualdad() {};
	virtual ~FactoryDesigualdad() {};
	virtual Desigualdad * newDesigualdad() = 0;
	virtual Desigualdad * newDesigualdad(const Desigualdad& otra) = 0;
};

template <class T>
class FactoryDesigualdadArray {
protected:
	FactoryDesigualdadArray() {};
	virtual ~FactoryDesigualdadArray() {};
	virtual DesigualdadArray<T> * newDesigualdadArray() = 0;
	virtual DesigualdadArray<T> * newDesigualdadArray(const DesigualdadArray<T>& otra) = 0;
};

#endif /* DESIGUALDAD_H_ */
